"""
Basilar commands
"""

from ev import utils
from game.gamesrc.commands.command import MyCommand


class CmdPut(MyCommand):
    """
    put

    Usage:
      put <obj> <container>
      put all <container>
      put <obj>.<index> <container>.<index>
      put <obj>.all <container>

    Puts one or more objects from your inventory in a container.    
    Only supports aliases, to get objects by object name you can use 
    underscore instead of space ("get A_knife" it's ok but not " get A knife")

    """
    key = "put"
    aliases = "metti"
    locks = "cmd:all()"
    help_category = "General"

    def func(self):
        "implements the command."

        caller = self.caller
        args = self.args

        if not args:
            caller.msg("Mettere cosa?")
            return

        n = 1
        if args[0][1].isdigit():
            n = int(args.pop(0)[1])

        if len(args) < 2:
            caller.msg("Dove?")
            return

        index, string = args[1] 
        dest = None

        if (string == "all" or index == ".all"):
            caller.msg("Non puoi!")
            return

        try:
            # this will search for containers as destination for objects,
            dest = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass
        
        if not dest:
            caller.msg("Dove lo vuoi mettere?")
            return

        if not 'CONTAINER' in dest.flags:
            caller.msg("Ma non e' un contenitore!")
            return

        if hasattr(dest, "is_closed") and dest.db.is_closed:
            caller.msg("Dovresti aprirlo prima di riuscire a mettere qualcosa li'!")
            return
            

        index, string = args[0] 
       
        objs = self.get_objects_from_string(index, string, caller, n)

        if not objs:
            caller.msg("Che cosa vuoi spostare?")
            return

        for element in objs:
            if not element.location == caller:
                caller.msg("Non hai quell'oggetto.")
                continue

            if element == dest:
                caller.msg("Non puoi metterlo dentro se' stesso!")
                continue
            if element in caller.db.equip.values():
                caller.msg("Non puoi metterlo da nessuna parte se prima non te lo togli da addosso.")
                continue


            element.move_to(dest, quiet=True)
            caller.msg("Metti %s dentro %s." % (element.name, dest.name))
            caller.location.msg_contents("%s mette %s dentro %s.", obj_list=[caller, element, dest],
                                                                   exclude=caller,
                                                                   wild_loc=caller.wild_loc)
            # calling hook method
            element.at_get(caller)





class CmdGive(MyCommand):
    """
    put

    Usage:
      give <obj> <someone>
      give all <someone>
      give <obj>.<index> <someone>.<index>
      give <obj>.all <someone>

    Gives one or more objects from your inventory to some other one.    
    Only supports aliases, to get objects by object name you can use 
    underscore instead of space ("get A_knife" it's ok but not " get A knife")

    """
    key = "give"
    aliases = "dai"
    locks = "cmd:all()"
    help_category = "General"

    def func(self):
        "implements the command."

        caller = self.caller
        args = self.args

        if not args:
            caller.msg("Cosa vorresti dare?")
            return

        n = 1
        if args[0][1].isdigit():
            n = int(args.pop(0)[1])


        if len(args) < 2:
            caller.msg("A chi?")
            return

        index, string = args[1] 
        dest = None

        if (string == "all" or index == ".all"):
            caller.msg("Non puoi!")
            return

        try:
            # this will search for people as destination for objects,
            #I know it's weird to search caller.contents... but one can't never tell...
            dest = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass

        if not dest:
            caller.msg("A chi lo vuoi dare?")
            return
        if dest == caller:
            caller.msg("Davvero vuoi dare qualcosa a te stesso?")
            return

        if not (dest.has_player or (hasattr(dest, "is_mob") and dest.is_mob)):
            caller.msg("Non puoi darglielo!")
            return
            

        index, string = args[0] 
       
        objs = self.get_objects_from_string(index, string, caller, n)

        if not objs:
            caller.msg("Che cosa vuoi dare?")
            return
        
        for element in objs:
            if not element.location == caller:
                caller.msg("Non hai quell'oggetto.")
                continue
            if element in caller.db.equip.values():
                caller.msg("Dovresti toglierlo prima prima di poterglielo dare.")
                continue



            element.move_to(dest, quiet=True)
            caller.msg("Dai %s a %s.", obj_list=[element, dest])
            dest.msg("%s ti da' %s.", obj_list=[caller, element])
            caller.location.msg_contents("%s da' %s a %s.", obj_list=[caller, element, dest],
                                                            exclude=[caller,dest],
                                                            wild_loc=caller.wild_loc)




class CmdOpenObject(MyCommand):
    """
    open

    Usage:
      open <obj>

    Open an object. If it's closed, of course.

    """
    key = "open"
    aliases = "apri"
    locks = "cmd:all()"

    def func(self):
        "implements the command."

        caller = self.caller
        
        if not self.args:
            caller.msg("Cosa vuoi aprire?")
            return

        index, string = self.args[0]
        target = None

        try:
            # this will search for a target
            target = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass

        if not target:
            caller.msg("Cosa vuoi aprire?")
            return

        if not 'LOCK' in target.flags:
            caller.msg("Ma non si puo' aprire!")
            return

        if hasattr(target, "is_locked") and target.db.is_locked:
            caller.msg("E' chiuso a chiave!")
            return

        if not target.db.is_closed:
            caller.msg("E' gia' aperto!")
            return

        target.open()

        name = target.name
        if hasattr(target, "door_name"):
            name = target.db.door_name

        caller.msg("Apri %s." % name)
        string = "x apre %s" % name
        string = string.replace("x", "%s")
        caller.location.msg_contents(string, obj_list=[caller],
                                 exclude=caller, wild_loc=caller.wild_loc)




class CmdCloseObject(MyCommand):
    """
    close

    Usage:
      close <obj>

    Close an open object.

    """
    key = "close"
    aliases = "chiudi"
    locks = "cmd:all()"
    help_category = "General"

    def func(self):
        "implements the command."

        caller = self.caller

        if not self.args:
            caller.msg("Cosa vuoi aprire?")
            return

        index, string = self.args[0]
        target = None

        try:
            # this will search for a target
            target = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass

        if not target:
            caller.msg("Cosa vuoi chiudere?")
            return

        if not 'LOCK' in target.flags:
            caller.msg("Ma non si puo' chiudere!")
            return

        if target.db.is_closed:
            caller.msg("E' gia' chiuso!")
            return

        target.close()

        name = target.name
        if hasattr(target, "door_name"):
            name = target.db.door_name

        caller.msg("Chiudi %s." % name)
        string = "x chiude %s" % name
        string = string.replace("x", "%s")
        caller.location.msg_contents(string, obj_list=[caller],
                                    exclude=caller,
                                    wild_loc=caller.wild_loc)


class CmdLockObject(MyCommand):
    """
    lock

    Usage:
      lock <obj>

    Lock an open object, if you have the key.

    """
    key = "lock"
    aliases = "blocca"
    locks = "cmd:all()"
    help_category = "General"

    def func(self):
        "implements the command."

        caller = self.caller

        if not self.args:
            caller.msg("Cosa vuoi chiudere?")
            return

        index, string = self.args[0]
        target = None

        try:
            # this will search for a target
            target = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass

        if not target:
            caller.msg("Cosa vuoi chiudere?")
            return

        if not hasattr(target, "keycode") or target.db.keycode == 0:
            caller.msg("Sembra che non si possa chiudere a chiave.")
            return

        if target.db.is_locked:
            caller.msg("E' gia' chiuso!")
            return

        if target.db.is_closed == False:
            caller.msg("E' aperto, non si puo' chiudere a chiave.")
            return

        keys = [element for element in caller.contents
                                         if 'KEY' in element.db.flags
                                         and element.keycode == target.keycode]

        name = target.name
        if hasattr(target, "door_name"):
            name = target.db.door_name

        if not keys:
            caller.msg("Ti serve la chiave giusta per chiudere %s." % name)
            return

        target.lock()

        caller.msg("Chiudi %s con %s." % (name, keys[0].name))
        string = "x chiude %s con x." % name
        string = string.replace("x", "%s")
        caller.location.msg_contents(string, obj_list=[caller, keys[0]],
                                                             exclude=caller,
                                                             wild_loc=caller.wild_loc)



class CmdUnlockObject(MyCommand):
    """
    unlock

    Usage:
      unlock <obj>

    Unlock a closed object, if you have the key.

    """
    key = "unlock"
    aliases = "sblocca"
    locks = "cmd:all()"

    def func(self):
        "implements the command."

        caller = self.caller

        if not self.args:
            caller.msg("Cosa vuoi aprire?")
            return

        index, string = self.args[0]
        target = None

        try:
            # this will search for a target
            target = self.get_objects_from_string(index, string, [caller, caller.location])[0]
        except IndexError:
            pass

        if not target:
            caller.msg("Cosa vuoi aprire?")
            return

        if not hasattr(target, "is_locked") or not target.db.is_locked: 
            caller.msg("%s non e' chiuso a chiave!" % target.name.capitalize())
            return

        keys = [element for element in caller.contents
                                         if 'KEY' in element.db.flags
                                         and element.keycode == target.keycode]


        name = target.name
        if hasattr(target, "door_name"):
            name = target.db.door_name

        if not keys:
            caller.msg("Ti serve la chiave giusta per aprire %s." % name)
            return

        target.unlock()
        caller.msg("Apri %s con %s." % (name, keys[0].name))
        string = "x apre %s con x." % name
        string = string.replace("x", "%s")
        caller.location.msg_contents(string, obj_list=[caller, keys[0]],
                                                           exclude=caller,
                                                           wild_loc=caller.wild_loc)






   
class CmdWear(MyCommand):
    """
    wear

    Usage:
      wear <obj>

    Wear an object.

    """
    key = "wear"
    aliases = ["wield", "indossa", "impugna"]
    locks = "cmd:all()"

    def func(self):
        "implements the command."

        caller = self.caller
        cmdstring = self.cmdstring
        verb = 'indossare'       
        if cmdstring == 'wield' or cmdstring == 'impugna': 
            verb = 'impugnare'

        if not self.args:
            caller.msg("Cosa vuoi %s?" % verb)
            return

        index, string = self.args[0]
        targets = None


        # this will search for a target
        targets = self.get_objects_from_string(index, string, [caller])

        # don't take weird stuff when taking multiple objects
        if len(targets) > 1:
            targets = [element for element in targets if hasattr(element, "slot")]

        if not targets:
            caller.msg("Cosa vuoi %s?" % verb)
            return
        for element in targets:
            new_verb = verb
            if not hasattr(element, "slot") or not element.slot or (verb == 'impugnare' and not 'Mano' in element.slot):
                caller.msg("Non si puo' %s." % verb)
                continue
            #if not caller.access(element, 'equip'):
            #    caller.msg("Non puoi equipaggiare questo oggetto.")
            #    continue
            if element in caller.db.equip.values():
                new_verb = new_verb[:-2] + "ndo"
                caller.msg("Stai gia' %s %s." % (new_verb, element.name))
                continue
            if caller.db.equip[element.slot] != None:
                caller.msg("Hai gia' qualcosa li'.")
                continue
            caller.db.equip[element.slot] = element
            new_verb = new_verb.replace("are","i")
            string = "%s x." % new_verb.capitalize()
            string = string.replace("x", "%s")
            caller.msg(string, obj_list=[element])
            new_verb = "%sa" % (new_verb[:-1])
            string = "x %s x." % new_verb
            string = string.replace("x", "%s")
            caller.location.msg_contents(string, obj_list=[caller, element],
                                                      exclude=caller, 
                                                      wild_loc=caller.wild_loc) 


class CmdRemove(MyCommand):
    """
    remove

    Usage:
      remove <obj>

    Remove an object from equip.

    """
    key = "remove"
    aliases = ["rem", "rimuovi", "togli"]
    locks = "cmd:all()"

    def func(self):
        "implements the command."

        caller = self.caller

        if not self.args:
            caller.msg("Cosa vuoi toglierti?")
            return

        index, string = self.args[0]
        targets = None

        # this will search for a target
        targets = self.get_objects_from_string(index, string, [caller])

        # don't take weird stuff when taking multiple objects
        if len(targets) > 1:
            targets = [element for element in targets if element in caller.db.equip.values()]

        if not targets:
            caller.msg("Cosa vuoi toglierti?")
            return

        for element in targets:
            if not element in caller.db.equip.values():
                caller.msg("Non stai indossando quell'oggetto.")
                continue
            caller.db.equip[element.slot] = None
            caller.msg("Togli %s.", obj_list=[element])
            caller.location.msg_contents("%s toglie %s.", obj_list=[caller, element],
                                                          exclude=caller,
                                                          wild_loc=caller.wild_loc)


class CmdEquip(MyCommand):
    """
    equip

    Usage:
      equip

    Show your current equipment.

    """
    key = "equip"
    aliases = ["eq"]
    locks = "cmd:all()"

    def func(self):
        "implements the command."
        caller = self.caller
        string = caller.show_equip(caller)
        if not string:
            string = "Non stai equipaggiando niente."
        caller.msg(string)
